From eb703737be5c91c1a0817351db8ec152c523c85d Mon Sep 17 00:00:00 2001
From: Alberto Milone <alberto.milone@canonical.com>
Date: Thu, 17 Sep 2015 15:49:46 +0200
Subject: [PATCH] Use a local copy of copy_xregs_to_kernel

This is needed for Linux 4.2.

Thanks to Tim Gardner for the patch.

Signed-off-by: Romain Perier <romain.perier@free-electrons.com>
---
 common/lib/modules/fglrx/build_mod/firegl_public.c | 44 +++++++++++++++++++++-
 1 file changed, 43 insertions(+), 1 deletion(-)

diff --git a/common/lib/modules/fglrx/build_mod/firegl_public.c b/common/lib/modules/fglrx/build_mod/firegl_public.c
index 4c1f9a5..bb67bba 100755
--- a/common/lib/modules/fglrx/build_mod/firegl_public.c
+++ b/common/lib/modules/fglrx/build_mod/firegl_public.c
@@ -6443,6 +6443,48 @@ int ATI_API_CALL kcl_sscanf(const char * buf, const char * fmt, ...)
     return i;
 }
 
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,2,0)
+/*
+ * Save processor xstate to xsave area.
+ */
+static void _copy_xregs_to_kernel(struct xregs_state *xstate)
+{
+        u64 mask = -1;
+        u32 lmask = mask;
+        u32 hmask = mask >> 32;
+        int err = 0;
+
+        /*WARN_ON(!alternatives_patched);*/
+
+        /*
+         * If xsaves is enabled, xsaves replaces xsaveopt because
+         * it supports compact format and supervisor states in addition to
+         * modified optimization in xsaveopt.
+         *
+         * Otherwise, if xsaveopt is enabled, xsaveopt replaces xsave
+         * because xsaveopt supports modified optimization which is not
+         * supported by xsave.
+         *
+         * If none of xsaves and xsaveopt is enabled, use xsave.
+         */
+        alternative_input_2(
+                "1:"XSAVE,
+                XSAVEOPT,
+                X86_FEATURE_XSAVEOPT,
+                XSAVES,
+                X86_FEATURE_XSAVES,
+                [xstate] "D" (xstate), "a" (lmask), "d" (hmask) :
+                "memory");
+        asm volatile("2:\n\t"
+                     xstate_fault(err)
+                     : "0" (err)
+                     : "memory");
+
+        /* We should never fault when copying to a kernel buffer: */
+        WARN_ON_FPU(err);
+}
+#endif
+
 /** \brief Generate UUID
  *  \param buf pointer to the generated UUID
  *  \return None
@@ -6462,7 +6504,7 @@ static int KCL_fpu_save_init(struct task_struct *tsk)
       fpu_xsave(fpu);
       if (!(fpu->state->xsave.xsave_hdr.xstate_bv & XSTATE_FP))
 #else
-      copy_xregs_to_kernel(&fpu->state.xsave);
+      _copy_xregs_to_kernel(&fpu->state.xsave);
       if (!(fpu->state.xsave.header.xfeatures & XSTATE_FP))
 #endif
 	 return 1;
-- 
2.8.1

